print("hello")

-- 单行注解
-- 操作符

--[[
    ~= :  不等于
    and ： 逻辑与操作符
    or ：逻辑或操作符
    not ： 逻辑非操作符
    .. : 字符串拼接
    # ： 长度操作符 ，string、table 、表达式 的长度  #"string" #table

--]]


-- 变量
--  默认情况下，变量总是认为是全局变量
--  所有变量都是有默认值的，即nil
--  变量不需要声明即可使用，和 js 差不多
--  不需要指定数据类型，也可随时 改变 变量的 数据类型
--  删除变量，只要给变量赋值nil 即可
--  创建局部变量必须使用 local 关键词 ；例如 ： local test = ' 你好'
--  局部变量的生命周期 ： 所在语句块
--  只要不加 local 关键词 ，无论 在任何地方 声明的变量 都是全局变量
print(b)

-- 数据类型
--[[
    nil : 空值，不占内存空间
    boolean : 包含 true,false
    number : 双精度浮点数
    string : 字符串 ，双引号或单引号表示，
    function : 函数 ，有C 或 lua 编写的函数
    userdata : 用来表示C语言数据结构 ，表示任意存储在变量中的 C 语言数据结构
    thread : 协程，可当成线程
    table ： 表 , 不固定长度, 相当于 数组 或 字典（Map）


--]]

-- type()  : 用于判断变量的类型
print(type("Hello world"))
-- nil 作比较时 应该加上引号
print(type(x)=='nil')

if false or nil then
    print("至少有一个是 true")
else
    print("false 和 nil 都为 false")
end
-- ----------------------------------------------
-- 字符串
-- 也可用 "[[]]" 表示多行字符串
html = [[
<html>
<head></head>
<body>
    <a href="http://www.runoob.com/">菜鸟教程</a>
</body>
</html>
]]
--print(html)

-- 字符串拼接符 ： ..
print("字符串A 拼接 - " ..'字符串B')

-- 字符串长度操作符 ： #
print("字符串长度 ： " ..#("2aaaa" ))

-- 字符串 进行算术运算时，会自动转换成 number ,后计算
print("计算结果 ： " ..("2" + 6))

-- table
-- 相当于字典结构， 就是Java 里的 Map 结构

-- 创建一个空的 table
local tbl1 = {}

-- 没有指定key的table, 相当于数组，可以通过下标访问
-- 【注意】table下标从 1 开始 ，和其他从 0 开始的不同
local tbl2 = {"apple", "pear", "orange", "grape"}
print('通过下表访问table: '.. tbl2[1])

--  指定 key 的table,相当于Map(字典)，可以通过key访问，不能通过下标访问
local tbl4 = {key1='nihao',key2='nihao22'}
local tbl3 = {}
tbl3['key1'] = 'nihao'
tbl3['key2'] = 'nihao22'
print('通过下表访问table: '.. tbl3['key1'])
tbl3['key1'] = '黑恶黑'
print('通过下表访问table: '.. tbl3['key1'])



-- function
-- 函数被当作 第一类公民，函数里 可以存在变量
-- 可以把函数当成一个 变量 使用

function factorial1(n)
    if n == 0 then
        return 1
    else
        return n * factorial1(n - 1)
    end
end

-- 匿名函数
func01 = function()
    if n == 0 then
        return 1
    else
        return n * factorial1(n - 1)
    end
end

func02 = func01

func02 ='你好' -- 把函数改成字符串

print(func02)

-- thread
-- 在lua里，最主要的线程就是协程，跟线程差不多，
-- 共同点 ： 拥有自己的栈、局部变量、和指令指针；可以跟其他协程共享全局变量
-- 不同点 ： 线程可以同时运行多个，而协程任意时刻只能运行一个，并且处于 运行中的协程 只有 被挂起时 才会暂停

-- userdata
-- 有其他程序或语言所创建的类型，存储在lua里被调用，一般是 指针或结构体（struct）


-- -----------------------------------------------------------------
-- lua 没有自增自减操作符 ++ ，--

-- if 语句

-- if(condition) then
--    <执行体>
-- end
if(0) then
    print("0 为 true")
end

-- if ..else 语句

-- if(condition) then
--     <执行体>
-- else
--     <执行体>
-- end

if( a < 20 ) then
    --[ if 条件为 true 时执行该语句块 --]
    print("a 小于 20" )
else
    --[ if 条件为 false 时执行该语句块 --]
    print("a 大于 20" )
end


-- if ..elseif...else 语句
-- if(condition) then
--     <执行体>
-- elseif( condition ) then
--     <执行体>
-- else
--     <执行体>
-- end
if( a == 10 ) then
    print("a 的值为 10" )
elseif( a == 20 ) then
    print("a 的值为 20" )
elseif( a == 30 ) then
    print("a 的值为 30" )
else
    print("没有匹配 a 的值" )
end

-- while 循环

-- while(condition) do
--     <执行体>
-- end

a=10
while( a < 20 ) do
    print("a 的值为:", a)
    a = a+1
end
-- for 循环 ：分为 数字for循环, 泛型for循环

-- 数字for循环

-- for var=exp1,exp2,exp3 do
--    <执行体>
-- end

-- exp1： 初始值 ； exp2 ：临界值 ； exp3 ： 步进

for i=10,1,-1 do
    print(i)
end

-- 泛型for循环

-- for key, value in ipairs( 集合 ) do
--     print(i, v)
-- end

-- key : 迭代索引 ； value ： 元素值 ； 迭代器 ：就是 table 类型 或 集合类型

a = {"one", "two", "three"}
for i, v in ipairs(a) do
    print(i, v)
end

-- repeat...until 循环
-- 相当于 do...while
-- 区别 ：如果条件判断语句（condition）为 false，循环会重新开始执行，直到条件判断语句（condition）为 true 才会停止执行。

-- repeat
--    statements
-- until( condition )

-- 【注意】condition == true ,停止循环； condition == false ,继续循环

a = 10
repeat
    print("a的值为:", a)
    a = a + 1
until( a > 15 )


-- break 语句 : 退出当前循环或语句，并开始脚本执行紧接着的语句。
a = 10

--[ while 循环 --]
while( a < 20 ) do
    print("a 的值为:", a)
    a=a+1
    if( a > 15) then
        break
    end
end
-- goto 语句 : 将程序的控制点转移到一个标签处。
local a = 1
::label:: print("--- goto label ---") -- goto 标记处

a = a+1
if a < 3 then
    goto label   -- a 小于 3 的时候跳转到标签 label
end
